package code.example.base.util.concurrent.lock.semaphore;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class SemaphoreByAQS  implements SemaphoreBy{

    Sync sync = null;
    public SemaphoreByAQS(int permit){
        sync = new Sync(permit);
    }

    class Sync extends AbstractQueuedSynchronizer{
        public Sync (int count){
            this.setState(count);
        }
        public int getPermit(){
            return this.getState();
        }
        @Override
        protected boolean tryAcquire(int arg) {
            for(;;){
                int state = this.getState();
                if(state >0){
                    int newState = state -1;
                    if(this.compareAndSetState(state,newState)){
                        return true;
                    }
                }else{
                    return false;
                }
            }
        }

        @Override
        protected boolean tryRelease(int arg) {
            for(;;){
                int state = this.getState();
                int newState = state +1;
                if(this.compareAndSetState(state,newState)){
                    return true;
                }
            }
        }
    }
    public void acquirePermit(){
        sync.acquire(1);
    }
    @Override
    public void releasePermit() {
        sync.release(1);
    }

    @Override
    public int getPermits() {
        return sync.getPermit();
    }
}
